﻿using Basmus.ReadWrite;

namespace Basmus.Values
{
    public class StringValuesService : IValuesService<string>
    {
        private readonly IContextService _contextService;
        private readonly IValuesService<object> _valueService;
        private readonly IBuilder<IElementsReaderWriter<object>> _builder;


        public StringValuesService(IContextService contextService, IValuesService<object> valueService, params IObjectElementsReaderWriterBuilder[] builders)
        {
            _contextService = contextService;
            _valueService = valueService;
            _builder = builders.Composite(x => x != null).Cached();
        }

        public void SetValues(ModelContext modelContext, object target, IValuesProvider<string> valuesProvider)
        {
            var valueContexts = _contextService.GetValuesContexts(modelContext);
            var objectValuesProvider = new ValuesProvider<object>();
            foreach (var valueContext in valueContexts)
            {
                var stringValues = valuesProvider.GetValues(valueContext.Name);
                var elementsReaderWriter = _builder.Build(valueContext);
                if (elementsReaderWriter != null)
                {
                    var values = elementsReaderWriter.Read(stringValues);
                    objectValuesProvider.Set(valueContext.Name, values);
                }
                else
                {
                    objectValuesProvider.Set(valueContext.Name, null);
                }
            }
            _valueService.SetValues(modelContext, target, objectValuesProvider);
        }

        public IValuesProvider<string> GetValues(ModelContext modelContext, object target)
        {
            var valuesProvider = new ValuesProvider<string>();
            var valuesContexts = _contextService
                .GetValuesContexts(modelContext);
            var objectValuesProvider = _valueService.GetValues(modelContext, target);
            foreach (var valuesContext in valuesContexts)
            {
                var values = objectValuesProvider.GetValues(valuesContext.Name);
                var elementsReaderWriter = _builder.Build(valuesContext);
                if (elementsReaderWriter != null)
                {
                    var strings = elementsReaderWriter.Write(values);
                    valuesProvider.Set(valuesContext.Name, strings);
                }
            }
            return valuesProvider;
        }
    }
}